#!/usr/local/bin/ruby19
#
#  get_devices.rb
#
#  Copyright (c) 2010-2011 Masoom Shaikh<masoom.shaikh@gmail.com>
#  All rights reserved.
# 
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
# 
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#  SUCH DAMAGE.

require 'ffi'

module Bluetooth
  extend FFI::Library

  NG_HCI_BDADDR_SIZE = 6      # unit address
  AF_BLUETOOTH       = 36     # Bluetooth sockets

  class Hostent < FFI::Struct
    layout :h_name, :string, # official name of host
      :h_aliases, :pointer,  # alias list
      :h_addrtype, :int,     # host address type
      :h_length, :int,       # length of address
      :h_addr_list, :pointer # list of addresses from name server
  end

  ffi_lib 'libbluetooth.so.4'

  # int bt_aton(char const *str, bdaddr_t *ba);
  attach_function :aton, :bt_aton, [:string, :buffer_out], :int

  # struct hostent* bt_gethostbyname(char const *name);
  attach_function :gethostbyname, :bt_gethostbyname, [:string], :pointer

  # struct hostent* bt_gethostbyaddr(char const *addr, int len, int type);
  attach_function :gethostbyaddr, :bt_gethostbyaddr, [:pointer, :int, :int], :pointer
end

# ret = Bluetooth.gethostbyname("Nighthawk")
# puts Bluetooth::Hostent.new(ret)[:h_name]

bdstr = "00:17:4b:5b:74:42"
bd = FFI::MemoryPointer.new( :uint8, Bluetooth::NG_HCI_BDADDR_SIZE)
if Bluetooth.aton( bdstr, bd) == 0
  printf("can't parse BD_ADDR %s\n", bdstr);
  exit(0)
end

hostent_ptr = Bluetooth.gethostbyaddr( bd, bd.size, Bluetooth::AF_BLUETOOTH)
if hostent_ptr.nil?
  printf("no name associated with %s\n", bdstr);
  exit(0)
end

hostent = Bluetooth::Hostent.new( hostent_ptr)
printf("name associated with %s is %s\n", bdstr, hostent[:h_name])
